本节标题:「武装思想」-React SSR vs SSR vs CSR
本节主旨:通过全面对比三种渲染模式,阐述为什么需要 react ssr
# 开篇
本文主要来介绍下SSR、CSR、React SSR 这三种渲染方式以及各自的优缺点。

# 什么是 SSR
SSR 的全称是Server Side Rendering,对应的中文名称是:服务端渲染,也就是将渲染的工作放在服务端进行。
这种方式很早就存在,早在 Ajax出现之前全部都是这种方式, 由服务端返回给浏览器完整的 html 内容。
浏览器得到完整的结构后就可直接进行 DOM 的解析、构建、加载资源及后续的渲染。
参考下图 jd 的产品详情,html 内包含具体的数据

# SSR 优缺点
这种页面(html)直出的方式可以让页面首屏较快的展现给用户,对搜索引擎比较友好,爬虫可以方便的找到页面的内容,非常有利于SEO。
不好的地方就是所有页面的加载都需要向服务器请求完整的页面内容和资源,访问量较大的时候会对服务器造成一定的压力,另外页面之间频繁刷新跳转的体验并不是很友好。
# 什么是 CSR
与 SSR 对应的就是 CSR,全称是 Client Side Rendering,也就是客户端渲染。
它是目前 Web 应用中主流的渲染模式,一般由 Server 端返回初始 HTML 内容,然后再由 JS 去异步加载数据,再完成页面的渲染。
客户端渲染模式中最流行的开发模式当属SPA(单页应用),所以后文都会基于SPA进行说明。
这种模式下服务端只会返回一个页面的框架和js 脚本资源,而不会返回具体的数据。
参考 弹个车www.tangeche.com,只有一个页面骨架和所需要的静态资源。
# CSR(SPA) 优缺点
页面之间的跳转不会刷新整个页面,而是局部刷新,体验上有了很大的提升。
单页应用中,只有首次进入或者刷新的时候才会请求服务器,只需加载一次js css资源,页面的路由维护在客户端,页面间的跳转就是切换相关的组件所以切换速度很快,另外数据渲染都在客户端完成,服务器只需要提供一个返回数据的接口,大大降低了服务器的压力。
所以后来就有了 web app的叫法,也是为了突出这种体验很像是Native App 。
SPA这种客户端渲染的方式在整体体验上有了很大的提升,但是它仍然有缺陷 - 对 SEO 不友好,页面首次加载可能有较长的白屏时间。
# SSR VS CSR(SPA)
找了很久才找到这个图,相信看过之后就明白了。
下面这张图,是同一个应用,用两种不同的方式去渲染时页面的加载时序。

- 橙色部分为页面背景色,对应了常规意义上的白屏时间
可以看到,从内容可见的时间上,SSR比CSR更快。
这是由于 SSR 的工作原理,决定了它的优势,这种差异在弱网环境下会体现的更加明显。
SPA(客户端渲染) 方式比 SSR (服务端渲染) 模式在体验和性能上有了很大的提升。
SPA 好处有很多,但缺点也很明显。
SEO 不够友好:有些网站的流量来源主要还是靠搜索引擎,所以网站的 SEO 效果 还是很重要的,而 SPA 模式页面数据非直出,搜索引擎爬虫拿不到具体的数据,所以无法对网站的内容进行识别和分类,得不到网站的关键词和描述信息,就无法进行排名,甚至不会被收录。结果就是在搜索引擎里搜不到你的站点。
首次白屏等待:在 SPA 模式下,第一次打开页面我们得到的是一个html 框架,不包含内容。数据的渲染需要等待页面js css资源加载完成,且执行时再发起异步数据请求,然后等数据返回后,再进行渲染,渲染完成后用户才能看到最终的页面。
这样做会直接降低页面的首屏展现时间,也就是“白屏”等待,这个时间的长短和客户端的网络环境也密切相关,可能长也可能短,特别是在移动互联网环境下,对首屏加载性能影响很大。对于用户来说,当然是想更快的看到内容。
# React SSR
到这里我们已经了解了 SSR 和 CSR 的概念以及优缺点。它们自身的亮点很多,但是瑕疵也很多。
SPA 模式下,虽然体验上来了,也降低了服务端的压力。但是还不算完美,仍有缺陷。
那么有没有一种完美的方式呢?
既然发现了问题,那就要想办法解决这个问题。
我们先来分析下。
确定问题:其实就两个问题
SEO不友好- 首次白屏等待。
以上两个问题是在传统 SSR 模式下是不存在的,因为服务端会直接返回完整的html数据。
所以如果要解决这个问题我们只能让数据直出 SSR 了。
但如果这样做的话,SPA 的优势就没有了,技术上没有任何进步。
# SSR + SPA 完美的结合
只实现 SSR 没什么意义,技术上没有任何改进,否则 SPA 技术就不会出现。
但是单纯的 SPA 又不够完美,所以最好的方案就是这两种技术和体验的结合。
第一次打开页面是服务端渲染,基于第一次访问,用户的后续交互是 SPA 的效果和体验,于此同时还能解决SEO问题,这就有点完美了。
单纯实现 SSR 很简单,毕竟这是传统技术,且和语言无关,随便用 php 、jsp、asp、node 等都可以实现。
下面用 node 实现一个基本的 ssr
- 创建一个
node服务 - 模拟数据请求方法
fetchData - 将
fetchData结果转换为html字符串 - 输出完整的
html内容
效果如下

const http = require('http');
//模拟数据的获取
const fetchData = function () {
return {
list: [{
name: '包子',
num: 100
},
{
name: '饺子',
num: 2000
}, {
name: '馒头',
num: 10
}
]
}
}
//数据转换为 html 内容
const dataToHtml=(data)=>{
var html='';
data.list.forEach(item=>{
html += `<div>${item.name}有${item.num}个</div>`
});
return html;
}
//服务
http.createServer((req, res) => {
res.writeHead(200, {
'Content-Type': 'text/html'
});
const html = dataToHtml(fetchData());
res.end(`<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>传统 ssr</title>
</head>
<body>
<div id="root">
${html}
</div>
</body>
</html>
</body>
`);
}).listen(9001);
console.log('server start...9001');
但是要实现两种技术的结合,同时可以最大限度的重用代码(同构),减少开发维护成本,那就需要采用 react 或者 vue 等前端框架和node(ssr)相结合的方式来实现。
csr 和 react ssr 从用户体验上来说差别不大,只是首次访问页面是 ssr直出,后续交互是 spa。
大家可以访问 https://m.xin.com/ 来体验下 react ssr 的体验,spa 的话可以体验下掘金,可同时右键查看源码,只有一个html骨架。
本文主要说 React SSR ,当然 VUE同样能实现,毕竟原理相同,只是技术栈不同而已。
React SSR 实现并不复杂,根据官方的说明,实现一个简单的组件直出也是分分钟。
但是这只能是个 demo,并不能应用到实际的项目开发中。
如果想用 react ssr 开发实际项目,我们就需要一个完整的开发框架,类似 nuxt.js next.js这样的框架,所以接下来我们将从react ssr 的原理出发,徒手实现一个完整的应用开发骨架。
请大家记住,我们要实现的是一个通用的应用开发骨架,有了这个骨架我们就可以快速的进入各种项目的业务开发,而不用关心 SSR 具体实现细节。
# 小结
本文主要是介绍了SSR CSR的概念,同时分析对比了它们的优缺点,最后引出了一种完美的实现方式CSR+SSR,也是我们后续实现React SSR的重要铺垫。
另外通过本文可以清晰的理解SSR+CSR 应用的优势以及该应用所独有的体验特点,让我们从宏观上对这种应用有一种基础的认知。